package fem2.observer;

import java.awt.GridLayout;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import ptolemy.plot.Plot;
import fem2.Observer;

public class XYGraphicalObserver extends JFrame implements Observer {

	private static final long serialVersionUID = 1L;

	private Plot plotTime = new Plot();

	private XYSourceObserver source;

	private Writer fileWriter = null;
	private boolean setWrite = false;

	public XYGraphicalObserver(XYSourceObserver source, String title) {
		this.source = source;

		this.setLayout(new GridLayout());
		this.add(this.plotTime);
		this.plotTime.setTitle(title);
		this.pack();
	}

	/**
	 * set the output to file
	 * 
	 * @param fileName
	 */
	public void setOutputToFile(String fileName) throws IOException {
		File file = new File(fileName);
		if (!file.exists()) {
			/*
			 * delete existing file
			 */
			file.delete();
			fileWriter = new BufferedWriter(new FileWriter(file, true));
		}
		/*
		 * create new file
		 */
		fileWriter = new BufferedWriter(new FileWriter(file));
		setWrite = true;
	}

	@Override
	public void fireStarted() {
		this.setVisible(true);
		/*
		 * add the first point
		 */
		this.plotTime.addPoint(0, source.getX(), source.getY(), true);
	}

	@Override
	public void fireTimeStepStarted() {

	}

	@Override
	public void fireIterationStarted() {

	}

	@Override
	public void fireIterationFinished() {

	}

	@Override
	public void fireTimeStepFinished() {
		this.plotTime.addPoint(0, source.getX(), source.getY(), true);
		/*
		 * refresh the painter
		 */
		SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				plotTime.repaint();
			}
		});
		/*
		 * write to file if needed
		 */
		if (setWrite) {
			try {
				fileWriter.write(Double.toString(source.getX()) + " "
						+ Double.toString(source.getY()) + "\n");
			} catch (IOException e) {
				e.printStackTrace();
				throw new Error("Write failed");
			}
		}
	}

	@Override
	public void fireFinished() {
		if (setWrite) {
			try {
				fileWriter.close();
			} catch (IOException e) {
				e.printStackTrace();
				throw new Error("Close failed");
			}
		}
	}

}
